package com.android.common.network;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Map.Entry;

import android.util.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.HttpVersion;
import ch.boye.httpclientandroidlib.client.HttpClient;
import ch.boye.httpclientandroidlib.client.methods.HttpGet;
import ch.boye.httpclientandroidlib.client.methods.HttpPost;
import ch.boye.httpclientandroidlib.conn.ConnectTimeoutException;
import ch.boye.httpclientandroidlib.conn.scheme.PlainSocketFactory;
import ch.boye.httpclientandroidlib.conn.scheme.Scheme;
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory;
import ch.boye.httpclientandroidlib.entity.mime.HttpMultipartMode;
import ch.boye.httpclientandroidlib.entity.mime.MultipartEntity;
import ch.boye.httpclientandroidlib.entity.mime.content.FileBody;
import ch.boye.httpclientandroidlib.entity.mime.content.StringBody;
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
import ch.boye.httpclientandroidlib.impl.conn.PoolingClientConnectionManager;
import ch.boye.httpclientandroidlib.params.BasicHttpParams;
import ch.boye.httpclientandroidlib.params.HttpConnectionParams;
import ch.boye.httpclientandroidlib.params.HttpParams;
import ch.boye.httpclientandroidlib.params.HttpProtocolParams;
import ch.boye.httpclientandroidlib.protocol.HTTP;

import com.android.common.ActivityManager;
import com.android.common.App;
import com.android.common.mobile.NetWork;
import com.android.common.util.FileUtil;

public class HttpDownloader {
	private static final String TAG = "HttpDownloader";
	private static final int TIMEOUT_CONNECTION = 5 * 1000; // 连接超时时间
	private static final int TIMEOUT_SOCKET = 20 * 1000; // 数据返回超时时间

	public static final String CONTENT_LENGTH = "content-length";// 头信息

	private static HttpClient httpClient = null;
	static {
		HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
		HttpConnectionParams.setConnectionTimeout(params, TIMEOUT_CONNECTION);
		HttpConnectionParams.setSoTimeout(params, TIMEOUT_SOCKET);
		SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http", 80, PlainSocketFactory
				.getSocketFactory()));
		registry.register(new Scheme("https", 443, SSLSocketFactory
				.getSocketFactory()));

		PoolingClientConnectionManager ccm = new PoolingClientConnectionManager(
				registry);
		ccm.setDefaultMaxPerRoute(20);
		ccm.setMaxTotal(80);
		httpClient = new DefaultHttpClient(ccm, params);
	}

	public static HttpResult getConnectInputStream(String url) {
		Log.v(TAG, "load url:" + url);
		HttpResult result = new HttpResult(HttpResult.API_RESULT_FAILED);
		result.fromContext = ActivityManager.getInstance()
				.getCurrentContextName();
		if (!NetWork.isNetworkAvailable(App.CONTEXT)) {
			result.resultCode = HttpResult.API_RESULT_NETWORK_CLOSE;
			return result;
		}

		try {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);
			// String length =
			// response.getFirstHeader(CONTENT_LENGTH).getValue();
			// TODO 检查长度

			result.resultCode = response.getStatusLine().getStatusCode();
			if (result.isSuccess()) {
				result.input = response.getEntity().getContent();
			} else {
				result.resultCode = HttpResult.API_RESULT_NETWORK_ERROR;
			}
		} catch (ConnectTimeoutException e) {
			result.resultCode = HttpResult.API_RESULT_NETWORK_TIMEOUT;
		} catch (Exception e) {
			Log.e(TAG, "getConnectInputStream error:", e);
		}
		Log.d(TAG, "code:" + result.resultCode + ",url:" + url);
		return result;
	}

	public static HttpResult getConnectData(String url) {
		HttpResult result = getConnectInputStream(url);
		if (!result.isSuccess()) {
			return result;
		}
		try {
			result.data = FileUtil.toByteArray(result.input);
		} catch (IOException e) {
			Log.e(TAG, "getConnectData error:", e);
		}
		return result;
	}

	public static HttpResult postConnectData(String url,
			Map<String, Object> params) {
		HttpResult result = post(url, params);
		if (!result.isSuccess()) {
			return result;
		}
		try {
			result.data = FileUtil.toByteArray(result.input);
		} catch (IOException e) {
			Log.e(TAG, "getConnectData error:", e);
		}
		return result;
	}

	public static HttpResult post(String url, Map<String, Object> params) {
		Log.v(TAG, "post url:" + url);
		HttpResult result = new HttpResult(HttpResult.API_RESULT_FAILED);
		result.fromContext = ActivityManager.getInstance()
				.getCurrentContextName();
		MultipartEntity entity = new MultipartEntity(
				HttpMultipartMode.BROWSER_COMPATIBLE);
		for (Entry<String, Object> param : params.entrySet()) {
			try {
				if (param.getValue() instanceof File) {
					entity.addPart(param.getKey(),
							new FileBody((File) param.getValue()));
				} else {
					entity.addPart(param.getKey(), new StringBody(param
							.getValue().toString(), Charset.forName("UTF-8")));
				}
			} catch (Exception e) {
				Log.e(TAG, "getConnectInputStream error:", e);
			}
		}

		HttpPost post = new HttpPost(url);
		post.setEntity(entity);
		try {
			HttpResponse response = httpClient.execute(post);
			result.resultCode = response.getStatusLine().getStatusCode();
			if (result.isSuccess()) {
				result.input = response.getEntity().getContent();
			} else {
				result.resultCode = HttpResult.API_RESULT_NETWORK_ERROR;
			}
		} catch (ConnectTimeoutException e) {
			result.resultCode = HttpResult.API_RESULT_NETWORK_TIMEOUT;
		} catch (Exception e) {
			Log.e(TAG, "getConnectInputStream error:", e);
		}
		Log.d(TAG, "code:" + result.resultCode + ",url:" + url);
		return result;
	}

}
